package com.cysyz.mylib.mailsender;

import com.cysyz.mylib.mailsender.exception.MailSendException;
import com.cysyz.mylib.utils.myassert.MyAssert;

import java.io.UnsupportedEncodingException;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

public class SMTPMailSender {
	private Session session;
	private String host;
	private final String id;
	private final String password;
	private String from;
	
	public SMTPMailSender(String host_, String id_, String password_) {
		MyAssert.matchRegex(host_, "smtp\\.[\\w\\W]+.[\\w\\W]", "smtp服务器地址格式错误，应该是stmp.163.com格式的地址。");
		MyAssert.hasText(id_);
		MyAssert.hasText(password_);

		String fromAddress = host_.substring(host_.indexOf(".") + 1);

		this.host = host_;
		id = id_;
		password = password_;
		from = id_ + "@" + fromAddress;

		init();
	}

	private void init() {
		Properties props = new Properties();
		props.setProperty("mail.transport.protocol", "smtp");
		props.setProperty("mail.host", this.host);
		props.setProperty("mail.debug", "true");
		props.setProperty("mail.smtp.auth", "true");
		session = Session.getInstance(props, new Authenticator() {
			@Override
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(id, password);
			}
		});
	}
	
	/**
	 * 
	 * @param fromAlias 显示名:<邮箱地址>
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private String getEndcodedAddress(String fromAlias) {
		StringBuilder fromBuilder = null;
		try {
			fromBuilder = new StringBuilder(MimeUtility.encodeText(fromAlias, "UTF-8", "B"));
		} catch (UnsupportedEncodingException e) {

		}

		fromBuilder.append("<");
		fromBuilder.append(from);
		fromBuilder.append(">");

		return fromBuilder.toString();
	}
	
	public Mail generateAMail(String fromAlias, String to, String[] ccs, String[] bccs, String subject, String htmlConent){
		Message msg = null;
		try {
			msg = new MimeMessage(session);
			msg.setSubject(subject);
			if (fromAlias != null && !fromAlias.isEmpty()) {
				msg.setFrom(new InternetAddress(getEndcodedAddress(fromAlias)));

			} else {
				msg.setFrom(new InternetAddress(from));
			}
			msg.addRecipient(RecipientType.TO, new InternetAddress(to));
			if (ccs != null) {
                for (String cc : ccs) {
                    msg.addRecipient(RecipientType.CC, new InternetAddress(getEndcodedAddress(cc)));
                }
            }
			if (bccs != null) {
                for (String bcc : bccs) {
                    msg.addRecipient(RecipientType.BCC, new InternetAddress(getEndcodedAddress(bcc)));
                }
            }
		} catch (MessagingException e) {
			throw new MailSendException(e);
		}
		return new Mail(msg, htmlConent);
	}
	
	public Mail generateAMail(String fromAlias, String to, String[] ccs, String subject, String htmlConent){
		return this.generateAMail(fromAlias, to, ccs, null, subject, htmlConent);
	}
	public Mail generateAMail(String fromAlias, String to, String subject, String htmlContent){
		return this.generateAMail(fromAlias, to, null, null, subject, htmlContent);
	}

	public Mail generateAMail(String to, String subject, String htmlContent){
		return this.generateAMail(null, to, null, null, subject, htmlContent);
	}
}
